{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Title: #Print in Order"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Difficulty: #Easy"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Category Title: #Concurrency"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Tag Slug: #concurrency"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Name Translated: #多线程"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solution Name: foobar"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Translated Title: #按序打印"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Translated Content:\n",
    "<p>给你一个类：</p>\n",
    "\n",
    "<pre>\n",
    "public class Foo {\n",
    "&nbsp; public void first() { print(\"first\"); }\n",
    "&nbsp; public void second() { print(\"second\"); }\n",
    "&nbsp; public void third() { print(\"third\"); }\n",
    "}</pre>\n",
    "\n",
    "<p>三个不同的线程 A、B、C 将会共用一个&nbsp;<code>Foo</code>&nbsp;实例。</p>\n",
    "\n",
    "<ul>\n",
    "\t<li>线程 A 将会调用 <code>first()</code> 方法</li>\n",
    "\t<li>线程 B 将会调用&nbsp;<code>second()</code> 方法</li>\n",
    "\t<li>线程 C 将会调用 <code>third()</code> 方法</li>\n",
    "</ul>\n",
    "\n",
    "<p>请设计修改程序，以确保 <code>second()</code> 方法在 <code>first()</code> 方法之后被执行，<code>third()</code> 方法在 <code>second()</code> 方法之后被执行。</p>\n",
    "\n",
    "<p><strong>提示：</strong></p>\n",
    "\n",
    "<ul>\n",
    "\t<li>尽管输入中的数字似乎暗示了顺序，但是我们并不保证线程在操作系统中的调度顺序。</li>\n",
    "\t<li>你看到的输入格式主要是为了确保测试的全面性。</li>\n",
    "</ul>\n",
    "\n",
    "<p>&nbsp;</p>\n",
    "\n",
    "<p><strong>示例 1：</strong></p>\n",
    "\n",
    "<pre>\n",
    "<strong>输入：</strong>nums = [1,2,3]\n",
    "<strong>输出：</strong>\"firstsecondthird\"\n",
    "<strong>解释：</strong>\n",
    "有三个线程会被异步启动。输入 [1,2,3] 表示线程 A 将会调用 first() 方法，线程 B 将会调用 second() 方法，线程 C 将会调用 third() 方法。正确的输出是 \"firstsecondthird\"。\n",
    "</pre>\n",
    "\n",
    "<p><strong>示例 2：</strong></p>\n",
    "\n",
    "<pre>\n",
    "<strong>输入：</strong>nums = [1,3,2]\n",
    "<strong>输出：</strong>\"firstsecondthird\"\n",
    "<strong>解释：</strong>\n",
    "输入 [1,3,2] 表示线程 A 将会调用 first() 方法，线程 B 将会调用 third() 方法，线程 C 将会调用 second() 方法。正确的输出是 \"firstsecondthird\"。</pre>\n",
    "\n",
    "<p>&nbsp;</p>\n",
    "\n",
    "<ul>\n",
    "</ul>\n",
    "<strong>提示：</strong>\n",
    "\n",
    "<ul>\n",
    "\t<li><code>nums</code> 是 <code>[1, 2, 3]</code> 的一组排列</li>\n",
    "</ul>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Description: [print-in-order](https://leetcode.cn/problems/print-in-order/description/)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solutions: [print-in-order](https://leetcode.cn/problems/print-in-order/solutions/)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_cases = ['[1,2,3]', '[1,3,2]']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import threading \n",
    "class FooBar:\n",
    "    def __init__(self, n):\n",
    "        self.n = n\n",
    "        self.s1=threading.Semaphore(1)\n",
    "        self.s2=threading.Semaphore(0)\n",
    "\n",
    "\n",
    "    def foo(self, printFoo: 'Callable[[], None]') -> None:\n",
    "        \n",
    "        for i in range(self.n):\n",
    "            \n",
    "            # printFoo() outputs \"foo\". Do not change or remove this line.\n",
    "            self.s1.acquire()\n",
    "            printFoo()\n",
    "            self.s2.release()\n",
    "\n",
    "\n",
    "    def bar(self, printBar: 'Callable[[], None]') -> None:\n",
    "        \n",
    "        for i in range(self.n):\n",
    "            \n",
    "            # printBar() outputs \"bar\". Do not change or remove this line.\n",
    "            self.s2.acquire()\n",
    "            printBar()\n",
    "            self.s1.release()\n",
    "\n",
    "# 作者：p瓜皮\n",
    "# 链接：https://leetcode.cn/problems/print-foobar-alternately/solutions/79145/python3-xin-hao-liang-pvcao-zuo-by-xjcai/\n",
    "# 来源：力扣（LeetCode）\n",
    "# 著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import threading \n",
    "class FooBar:\n",
    "    def __init__(self, n):\n",
    "        self.n = n\n",
    "        self.s1=threading.Semaphore(1)\n",
    "        self.s2=threading.Semaphore(0)\n",
    "\n",
    "\n",
    "    def foo(self, printFoo: 'Callable[[], None]') -> None:\n",
    "        \n",
    "        for i in range(self.n):\n",
    "            \n",
    "            # printFoo() outputs \"foo\". Do not change or remove this line.\n",
    "            self.s1.acquire()\n",
    "            printFoo()\n",
    "            self.s2.release()\n",
    "\n",
    "\n",
    "    def bar(self, printBar: 'Callable[[], None]') -> None:\n",
    "        \n",
    "        for i in range(self.n):\n",
    "            \n",
    "            # printBar() outputs \"bar\". Do not change or remove this line.\n",
    "            self.s2.acquire()\n",
    "            printBar()\n",
    "            self.s1.release()\n",
    "\n",
    "# 作者：p瓜皮\n",
    "# 链接：https://leetcode.cn/problems/print-foobar-alternately/solutions/79145/python3-xin-hao-liang-pvcao-zuo-by-xjcai/\n",
    "# 来源：力扣（LeetCode）\n",
    "# 著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。"
   ]
  }
 ],
 "metadata": {},
 "nbformat": 4,
 "nbformat_minor": 2
}
